home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / upc12bs1.zip / UUCICO / script.c < prev    next >
C/C++ Source or Header  |  1993-10-03  |  17KB  |  494 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    s c r i p t . c                                                 */
  3. /*                                                                    */
  4. /*    Script processing routines for UUPC/extended                    */
  5. /*                                                                    */
  6. /*    John H. DuBois III  3/31/90                                     */
  7. /*--------------------------------------------------------------------*/
  8.  
  9. /*--------------------------------------------------------------------*/
  10. /*                        System include files                        */
  11. /*--------------------------------------------------------------------*/
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <ctype.h>
  16. #include <string.h>
  17. #include <time.h>
  18.  
  19. /*--------------------------------------------------------------------*/
  20. /*                    UUPC/extended include files                     */
  21. /*--------------------------------------------------------------------*/
  22.  
  23. #include "lib.h"
  24. #include "dcp.h"
  25. #include "dcpsys.h"
  26. #include "hostable.h"
  27. #include "hlib.h"
  28. #include "modem.h"
  29. #include "script.h"
  30. #include "security.h"
  31. #include "ssleep.h"
  32. #include "catcher.h"
  33. #include "usrcatch.h"
  34. #include "commlib.h"
  35.  
  36. /*--------------------------------------------------------------------*/
  37. /*                           Local defines                            */
  38. /*--------------------------------------------------------------------*/
  39.  
  40. #define MAXMATCH 64              /* max length of search string; must
  41.                                     be a power of 2                  */
  42. #define QINDMASK (MAXMATCH - 1)  /* bit mask to get queue index      */
  43.  
  44. #define EOTMSG "\004\r\004\r"
  45.  
  46. /*--------------------------------------------------------------------*/
  47. /*                    Internal function prototypes                    */
  48. /*--------------------------------------------------------------------*/
  49.  
  50. static int StrMatch(char *MatchStr, char C, char **failure);
  51.                                  /* Internal match routine           */
  52.  
  53. static boolean Match( char *Search,
  54.                       char *Buffer,
  55.                       size_t *SearchPos);
  56.  
  57. static size_t MatchInit( const char *MatchStr );
  58.  
  59. static void writestr(register char *s);
  60.  
  61. static void flushScriptBuffer( void );
  62.  
  63. static void slowWrite( char *s, size_t len);
  64.  
  65. /*--------------------------------------------------------------------*/
  66. /*                          Global variables                          */
  67. /*--------------------------------------------------------------------*/
  68.  
  69. currentfile();
  70.  
  71. static char scriptBuffer[40];    // Can be shorter then longest send
  72.                                  // string, as longer strings are
  73.                                  // send without buffering
  74.  
  75. static size_t scriptBufferLen = 0;
  76.  
  77. /*--------------------------------------------------------------------*/
  78. /*       e x p e c t s t r                                            */
  79. /*                                                                    */
  80. /*       wait for a pattern on input                                  */
  81. /*                                                                    */
  82. /*       expectstr reads characters from input using sread, and       */
  83. /*       compares them to a search string.  It reads characters       */
  84. /*       until either the search string has been seen on the input    */
  85. /*       or a specified timeout interval has passed without any       */
  86. /*       characters being read.                                       */
  87. /*                                                                    */
  88. /*      Global variables: none.                                       */
  89. /*                                                                    */
  90. /*      Input parameters:                                             */
  91. /*      Search is the string that is searched for on the input.       */
  92. /*      Timeout is the timeout interval passed to sread.              */
  93. /*                                                                    */
  94. /*      Output parameters: none.                                      */
  95. /*                                                                    */
  96. /*      Return value:                                                 */
  97. /*      TRUE is returned if the search string is found on input.      */
  98. /*      FALSE is returned if sread times out.                         */
  99. /*--------------------------------------------------------------------*/
  100.  
  101. int expectstr(char *Search, unsigned int Timeout, char **failure)
  102. {
  103.    char buf[BUFSIZ];
  104.    int result;
  105.    time_t quit = time( NULL ) + Timeout;
  106.    register char *ptr = buf;
  107.  
  108.    printmsg(2, "wanted \"%s\"", Search);
  109.  
  110.    if (!strlen(Search))                      /* expects nothing */
  111.        return TRUE;
  112.  
  113.    StrMatch(Search,'\0', failure);    /* set up search string */
  114.  
  115.    do {
  116.       if (ptr == &buf[BUFSIZ-1])
  117.         ptr = buf;          /* Save last character for term \0  */
  118.  
  119.       if (sread(ptr , 1, (int) (quit - time(NULL))) < 1)
  120.       {
  121.                               /* The scan failed?                    */
  122.          char *s;
  123.  
  124.          if ( terminate_processing || raised )
  125.             return 0;
  126.  
  127.          while ( ptr > buf )
  128.             if (*(--ptr) > ' ')
  129.                break;    /* Locate the last printable char      */
  130.  
  131.          *(ptr+1) = '\0';   /* Terminate the string             */
  132.  
  133.          for ( s = buf; (*s > '\0') && (*s <= ' '); s++ );
  134.                             /* Locate the first printable char  */
  135.  
  136.          while ( ptr-- > s )/* Zap control chars                */
  137.             if (*ptr < ' ')
  138.                *ptr = '?';
  139.  
  140.          if ( debuglevel < 2 )
  141.             printmsg(1, "wanted \"%s\"", Search);
  142.  
  143.          printmsg(1, "got ??? \"%s\"",s );
  144.          return FALSE;
  145.  
  146.       } /* if (sread(ptr , 1, Timeout) < 1) */
  147.  
  148.       *ptr &= 0x7f;
  149.  
  150.       result = StrMatch(Search, *ptr++, failure);
  151.    } while (!result);
  152.  
  153.    return result;
  154.  
  155. } /*expectstr*/
  156.  
  157. /*
  158.  *      StrMatch: Incrementally search for a string.
  159.  *      John H. DuBois III  3/31/90
  160.  *      StrMatch searches for a string in a sequence of characters.
  161.  *      The string to search for is passed in an initial setup call
  162.  *      (input character in this call is \0)
  163.  *      Further calls with the search string pass one
  164.  *      character per call.
  165.  *      The characters are built up into an input string.
  166.  *      After each character is added to the input string,
  167.  *      the search string is compared to the last length(search string)
  168.  *      characters of the input string to determine whether the search
  169.  *      string has been found.
  170.  *
  171.  *      Global variables: none.
  172.  *
  173.  *      Input parameters:
  174.  *      MatchStr is the string to search for.
  175.  *      C is the character to add to the input string.
  176.  *      It is ignored on a setup call.
  177.  *
  178.  *      Output parameters: None.
  179.  *
  180.  *      Return value:
  181.  *      On the setup call, -1 is returned if the search string is
  182.  *      longer than the input string buffer.  Otherwise, 0 is returned.
  183.  *
  184.  *      On comparison calls,
  185.  *          1 is returned if the search string has been found.
  186.  *          > 1 is returned if a failure string has been found.
  187.  *          Otherwise 0 is returned.
  188.  */
  189.  
  190. static int StrMatch(char *MatchStr, char C, char **failure)
  191. {
  192. /*
  193.  *      The input string is stored in a circular buffer of MAXMATCH
  194.  *      characters.  If the search string is found in the input,
  195.  *      then the last character added to the buffer will be the last
  196.  *      character of the search string.  Therefore, the string
  197.  *      compare will always start SearchLen characters behind the
  198.  *      position where characters are added to the buffer.
  199.  */
  200.  
  201.    static char Buffer[MAXMATCH];       /* Input string buffer */
  202.    static size_t PutPos;               /* Where to add chars to buffer */
  203.  
  204.    static size_t SearchPos[MAXLIST];
  205.    static size_t SearchPosition;
  206.                                        /* Buffer loc to start compare */
  207.    static size_t alternates;
  208.    size_t subscript;
  209.  
  210. /*--------------------------------------------------------------------*/
  211. /*                       Handle initialize call                       */
  212. /*--------------------------------------------------------------------*/
  213.  
  214.    if ( C == '\0')
  215.    {                                   /* Set up call */
  216.       memset(Buffer,'\0',MAXMATCH);    /* Clear buffer */
  217.       PutPos = 0;
  218.  
  219.       SearchPosition = MatchInit( MatchStr );
  220.  
  221.       alternates = 0;
  222.       if ( failure != NULL )
  223.       {
  224.          while (failure[alternates] != NULL )
  225.          {
  226.             SearchPos[alternates] = MatchInit( failure[alternates] );
  227.             alternates++;
  228.          } /* while (failure[alternates] != NULL ) */
  229.  
  230.       } /* if ( failure != NULL ) */
  231.  
  232.       return 0;
  233.    } /* if (MatchStr) */
  234.  
  235. /*--------------------------------------------------------------------*/
  236. /*                       Look for primary match                       */
  237. /*--------------------------------------------------------------------*/
  238.  
  239.    Buffer[ PutPos++ & QINDMASK] = C;
  240.  
  241.    if (Match( MatchStr, Buffer, &SearchPosition))
  242.    {
  243.       printmsg(2, "got that");
  244.       return 1;
  245.    }
  246.  
  247. /*--------------------------------------------------------------------*/
  248. /*                     Look for alternate matches                     */
  249. /*--------------------------------------------------------------------*/
  250.  
  251.    if ( alternates > 0 )
  252.    {
  253.       subscript = alternates;
  254.  
  255.       while ( subscript-- )
  256.       {
  257.          if (Match( failure[subscript], Buffer, &SearchPos[subscript]))
  258.          {
  259.             printmsg(0,"got \"%s\" (failure)",failure[subscript]);
  260.             return 2;
  261.          }
  262.       } /* while ( subscript-- ) */
  263.  
  264.    } /* if ( alternates > 0 ) */
  265.  
  266.    return 0;
  267.  
  268. } /* StrMatch */
  269.  
  270. /*--------------------------------------------------------------------*/
  271. /*    m a t c h                                                       */
  272. /*                                                                    */
  273. /*    Match a single string                                           */
  274. /*--------------------------------------------------------------------*/
  275.  
  276. static boolean Match( char *Search,
  277.                       char *Buffer,
  278.                       size_t *SearchPos)
  279. {
  280.    int BufInd;             /* Index to input string buffer for string
  281.                               compare */
  282.    char *SearchInd;        /* Index to search string for string
  283.                               compare */
  284.  
  285.    *SearchPos += 1;
  286.    for (BufInd = *SearchPos, SearchInd = Search; *SearchInd; SearchInd++)
  287.    {
  288.      if (Buffer[BufInd++ & QINDMASK] != *SearchInd)
  289.         return FALSE;
  290.    }
  291.  
  292.    return TRUE;
  293.  
  294. } /* Match */
  295.  
  296. /*--------------------------------------------------------------------*/
  297. /*    M a t c h I n i t                                               */
  298. /*                                                                    */
  299. /*    Initialize one set of parameters for MATCH                      */
  300. /*--------------------------------------------------------------------*/
  301.  
  302. static size_t MatchInit( const char *MatchStr )
  303. {
  304.    size_t SearchLen = strlen(MatchStr);
  305.  
  306.    if (SearchLen > MAXMATCH)
  307.    {
  308.       printmsg(0,"StrMatch: String to match '%s' is too long.\n",
  309.            MatchStr);
  310.       panic();
  311.    }
  312.  
  313.    return MAXMATCH - SearchLen;
  314.  
  315. } /* MatchInit */
  316.  
  317. /*--------------------------------------------------------------------*/
  318. /*    w r i t e s t r                                                 */
  319. /*                                                                    */
  320. /*    Send a string to the port during login                          */
  321. /*--------------------------------------------------------------------*/
  322.  
  323. static void writestr(register char *s)
  324. {
  325.    register char last = '\0';
  326.    boolean writeCR = TRUE;
  327.    unsigned char digit;
  328.  
  329.    while (*s)
  330.    {
  331.       if (last == '\\') {
  332.          last = *s;
  333.          switch (*s) {
  334.          case 'd':   /* delay */
  335.          case 'D':
  336.             flushScriptBuffer();
  337.             ssleep(2);
  338.             break;
  339.          case 'c':   /* don't output CR at end of string */
  340.          case 'C':
  341.             writeCR = FALSE;
  342.             break;
  343.          case 'r':   /* carriage return */
  344.          case 'R':
  345.          case 'm':
  346.          case 'M':
  347.             slowWrite("\r", 1);
  348.             break;
  349.          case 'n':   /* new line */
  350.          case 'N':
  351.             slowWrite("\n", 1);
  352.             break;
  353.          case 'p':   /* delay */
  354.          case 'P':
  355.             flushScriptBuffer();
  356.             ddelay(400);
  357.             break;
  358.          case 'b':   /* backspace */
  359.          case 'B':
  360.             slowWrite("\b", 1);
  361.             break;
  362.          case 't':   /* tab */
  363.          case 'T':
  364.             slowWrite("\t", 1);
  365.             break;
  366.          case 's':   /* space */
  367.          case 'S':
  368.             slowWrite(" ", 1);
  369.             break;
  370.          case 'z':   /* set serial port speed */
  371.          case 'Z':
  372.             flushScriptBuffer();
  373.             SIOSpeed(atoi(++s));
  374.             while (isdigit(*(s+1)))
  375.                s++;
  376.             break;
  377.  
  378.          case '0':
  379.          case '1':
  380.          case '2':
  381.          case '3':
  382.          case '4':
  383.          case '5':
  384.          case '6':
  385.          case '7':
  386.             digit = 0;
  387.             while( (*s >= '0') && (*s < '8'))
  388.                digit = (unsigned char) (digit * 8 + *s++ - '0');
  389.             s--;              /* Backup before non-numeric char      */
  390.             slowWrite((char *) &digit,1);
  391.             break;
  392.  
  393.          default: /* ordinary character */
  394.             slowWrite(s, 1);
  395.             last = '\0';      /* Zap any repeated backslash (\)      */
  396.          }
  397.       }
  398.       else if (*s != '\\') /* backslash */
  399.          slowWrite(s, 1);
  400.       else
  401.          last = *s;
  402.       s++;
  403.  
  404.    }  /* while */
  405.  
  406.    if ( writeCR )
  407.       slowWrite( "\r", 1 );
  408.  
  409.    flushScriptBuffer();             // Handle any queued data on net
  410.  
  411. } /* writestr */
  412.  
  413. /*--------------------------------------------------------------------*/
  414. /*       s e n d s t r                                                */
  415. /*                                                                    */
  416. /*       Send line of login sequence                                  */
  417. /*--------------------------------------------------------------------*/
  418.  
  419. void sendstr(char *str)
  420. {
  421.    printmsg(2, "sending \"%s\"", str);
  422.  
  423.    if (equaln(str, "BREAK", 5))
  424.    {
  425.       int   nulls;
  426.       nulls = atoi(&str[5]);
  427.       if (nulls <= 0 || nulls > 10)
  428.          nulls = 3;
  429.       ssendbrk(nulls);  /* send a break signal */
  430.       return;
  431.    }
  432.  
  433.    if (equal(str, "EOT"))
  434.    {
  435.       slowWrite(EOTMSG, strlen(EOTMSG));
  436.       flushScriptBuffer();
  437.       return;
  438.    }
  439.  
  440.    if (equal(str, "\"\""))
  441.       *str = '\0';
  442.  
  443.    writestr(str);
  444.  
  445. } /*sendstr*/
  446.  
  447. /*--------------------------------------------------------------------*/
  448. /*    s l o w w r i t e                                               */
  449. /*                                                                    */
  450. /*    Write characters to the serial port at a configurable           */
  451. /*    snail's pace.                                                   */
  452. /*--------------------------------------------------------------------*/
  453.  
  454. static void slowWrite( char *s, size_t len)
  455. {
  456.    if ( M_charDelay )
  457.    {
  458.       swrite( s , len );
  459.       ddelay(M_charDelay);
  460.    }
  461.    else {
  462.  
  463.       if ( (scriptBufferLen + len) > sizeof scriptBuffer )
  464.          flushScriptBuffer();
  465.  
  466.       if ( len == 1 )
  467.          scriptBuffer[ scriptBufferLen++ ] = *s;
  468.       else if ( len >= sizeof scriptBuffer )
  469.          swrite( s , len );
  470.       else {
  471.          memcpy( scriptBuffer + scriptBufferLen, s, len );
  472.          scriptBufferLen += len;
  473.       } /* else */
  474.  
  475.    } /* else */
  476.  
  477. } /* slowWrite */
  478.  
  479. /*--------------------------------------------------------------------*/
  480. /*       f l u s h S c r i p t B u f f e r                            */
  481. /*                                                                    */
  482. /*       Flush queued network I/O                                     */
  483. /*--------------------------------------------------------------------*/
  484.  
  485. static void flushScriptBuffer( void )
  486. {
  487.    if ( scriptBufferLen )
  488.    {
  489.       swrite( scriptBuffer, scriptBufferLen );
  490.       scriptBufferLen = 0;
  491.    }
  492.  
  493. } /* flushScriptBuffer */
  494.